/*
* See LICENSE for licensing and NOTICE for copyright.
*/
package net.shibboleth.idp.cas.authn;
import java.net.URI;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.security.auth.login.FailedLoginException;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.logic.Constraint;
/**
* Abstract base class for proxy callback authentication by means of validating an HTTPS endpoint.
*
* @author Marvin S. Addison
*/
public abstract class AbstractProxyAuthenticator implements Authenticator<URI, Void> {
/** Required https scheme for proxy callbacks. */
protected static final String HTTPS_SCHEME = "https";
/** List of HTTP response codes permitted for successful proxy callback. */
@NotEmpty
@NonnullElements
private Set<Integer> allowedResponseCodes = Collections.singleton(200);
/**
* Sets the HTTP response codes permitted for successful authentication of the proxy callback URL.
*
* @param responseCodes One or more HTTP response codes.
*/
public void setAllowedResponseCodes(@NotEmpty @NonnullElements final Set<Integer> responseCodes) {
Constraint.isNotEmpty(responseCodes, "Response codes cannot be null or empty.");
Constraint.noNullItems(responseCodes.toArray(), "Response codes cannot contain null elements.");
this.allowedResponseCodes = responseCodes;
}
@Override
public Void authenticate(@Nonnull final URI credential) throws GeneralSecurityException {
Constraint.isNotNull(credential, "URI to authenticate cannot be null.");
if (!HTTPS_SCHEME.equalsIgnoreCase(credential.getScheme())) {
throw new GeneralSecurityException(credential + " is not an https URI as required.");
}
final int status = authenticateProxyCallback(credential);
if (!allowedResponseCodes.contains(status)) {
throw new FailedLoginException(credential + " returned unacceptable HTTP status code " + status);
}
return null;
}
/**
* Authenticates the proxy callback URI by making an HTTP GET request and returning the HTTP response code.
*
* @param callbackUri Proxy callback URI containing requisite CAS protocol parameters, <code>pgtId</code> and
* <code>pgtIou</code>.
*
* @return Status code from HTTP GET request.
*
* @throws GeneralSecurityException On a failure related to establishing the HTTP connection due to SSL/TLS errors.
* @throws RuntimeException On networking errors (IO, HTTP protocol).
*/
protected abstract int authenticateProxyCallback(URI callbackUri) throws GeneralSecurityException;
}